Unix网络编程-第1章 简介

源代码下载:http://www.unpbook.com/

源代码使用方法见解压后的README文件

TCP是一个没有记录边界的字节流协议,TCP本身并不提供记录结束的标志:如果应用程序需要确定记录的边界,它就要自己去实现,已有的一些常用的方法可供选择。

迭代服务器:对于每个客户都迭代执行一次。

并发服务器:同时能处理多个客户。

原始套接字:网络应用绕过传输层直接使用IPv4或IPv6。

为什么套接字提供的是从OSI模型的顶上三层进入传输层的接口?

理由有两:

  1. 顶上三层处理具体网络应用的所有细节,却对通信细节了解很少;底下四层对具体网络应用了解不多,却处理所有的通信细节:发送数据,等待确认,给无序到达的数据排序,计算并验证校验和,等等。
  2. 顶上三层通常构成所谓的用户进程(user process),底下四层却通常作为操作系统内核的一部分提供。Unix与其他现代操作系统都提供分隔用户进程与内核的机制。

由此可见,第4层和第5层之间的接口是构建API的的自然位置。

image-20210313172914195

image-20210122104917940

网络拓扑的发现

  1. netstat -ni,提供网络接口信息,-n标志指定输出数值地址
  2. netstat -nr,展示路由表,-n标志指定输出数值地址
  3. ifconfig,查看所有接口详细信息
  4. ifconfig eth0,查看eth0接口的详细信息

POSIX是Portable Operating System Interface的首字母的缩写,可移植操作系统接口。

现有32位Unix系统上共同的编程模型称为ILP32模型,表示整数(I)、长整数(L)、指针(P)都占用32位

64位Unix系统上变得最为流行的模型称为LP64模型,表示只有长整数(L)、指针(P)占用64位

LP64模型意味着我们不能假设一个指针能存放在一个整数中。

数据类型ILP32LP64
char88
short1616
int3232
long3264
指针3264

章节末习题:

第三题:

修改client socket(AF_INET, SOCK_STREAM, 0) AF_INET成9999,结果报socket error: Address family not supported by protocol family ,经查询:AF_INET本身代表了protocol family的一个特殊标记值,如果修改成其他值,相当于一个新的protocol family,那么之后传入的address family当然不会支持了。

第四题:

client增加一个计数器并打印。

int counter = 0;

while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
    counter++;
    recvline[n] = 0;    /* null terminate */
    if (fputs(recvline, stdout) == EOF)
        err_sys("fputs error");
}

printf("%d\n",counter);

第五题:

修改server端代码,将原本完整的内容,单字节发送,并查看client端实际执行的read次数。

snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));

for (int i = 0; i < strlen(buff); ++i) {
    Write(connfd, &(buff[i]), 1);
}

Close(connfd);

实际执行client端,每次执行read的counter都在变化。